#include <slothttpd/config/location/base_location.hpp>
#include <slothttpd/config/configuration.hpp>
#include <slothttpd/http/http.hpp>
#include <slothttpd/config/server.hpp>

#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/trim.hpp>

namespace slothttpd {
namespace config {

base_location::base_location(const boost::property_tree::ptree &node, server &s) :
    loc_server(s)
{
    for (auto &v : node.get_child("match")) {
        auto &m = v.second.data();
        
        match.push_back(create_matcher(m));
        match_patters.push_back(m);
    }
    
    dest = node.get<std::string>("dest");
    path = boost::filesystem::path(node.get<std::string>("path", s.path)).normalize().string();
    
    auto it = node.find("headers");
    if (it != node.not_found()) {
        for (auto &v : it->second) {
            headers.push_back(v.first.data() + http::semicolon + v.second.data() + http::crlf);
            header_buffers.push_back(boost::asio::buffer(headers.back()));
        }
    }
}

base_location::~base_location()
{
}

bool base_location::base_location::match_path(char_range_t path) const
{
    for (auto &m : match) {
        if (m(path))
            return true;
    }
    
    return false;
}

std::ostream &operator<<(std::ostream &os, const base_location &loc)
{
    std::vector<std::string> seq;
    
    for (auto &h : loc.headers) {
        seq.push_back(boost::algorithm::trim_copy(h));
    }
    
    os << "      --- location ---\n"
       << "          match  : " << boost::algorithm::join(loc.match_patters, ", ") << '\n'
       << "          dest   : " << loc.dest << '\n'
       << "          headers: " << boost::algorithm::join(seq, ", ") << '\n';
    
    return os;
}

}
}
